home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1994 January / PSL Monthly Shareware CD-ROM (Public Software Library) (January 1994).iso / games / dos / misc / monster.com / MONSTER.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-05-03  |  5.8 KB  |  406 lines

  1.     NAME    Cookie
  2.  
  3. ; Cookie monster.  Memory resident program that wakes up after a while
  4. ; and demands a cookie using a digitized voice played on the PC's speaker.
  5. ; User must type "cookie" to make the cookie monster happy.
  6.  
  7. TEXT    SEGMENT BYTE PUBLIC 'CODE'
  8. TEXT    ENDS
  9.  
  10. STK    SEGMENT STACK
  11.     DW    128 DUP (0)
  12. STK    ENDS
  13.  
  14.     ASSUME    CS:TEXT, DS:TEXT, ES:TEXT, SS:STK
  15.  
  16. countr    EQU    72        ; 16572 Hz
  17.  
  18. tcadrc    EQU    43h
  19. tcadrd    EQU    40h
  20.  
  21. tcmode    EQU    34h
  22. tc2mode EQU    0B8h
  23.  
  24. ppiadr    EQU    61h
  25.  
  26. fuselen EQU    20        ; length of fuse
  27.  
  28. EXTRN    Giveme:NEAR, Givemelen:WORD
  29. EXTRN    Yum:NEAR, Yumlen:WORD
  30.  
  31. TEXT    SEGMENT
  32.  
  33. Messptr DW    0
  34. Messcnt DW    0
  35. Fuse1    DW    0
  36. Fuse2    DW    0
  37.  
  38. start:
  39.     push    cs        ; set ds
  40.     pop    ds
  41.  
  42. ; Set initial short fuse.
  43.  
  44.     mov    Fuse1,0
  45.     mov    Fuse2,1
  46.  
  47. ; Add to int 28h chain.
  48.  
  49.     mov    ax,3528h
  50.     int    21h
  51.     mov    WORD PTR Oldint28,bx
  52.     mov    WORD PTR Oldint28+2,es
  53.  
  54.     mov    dx,OFFSET int28
  55.     mov    ax,2528h
  56.     int    21h
  57.  
  58. ; Terminate and stay resident.
  59.  
  60.     mov    dx,SEG HIGHMEM
  61.     mov    ax,cs
  62.     sub    dx,ax
  63.     mov    ax,3100h
  64.     int    21h
  65.  
  66. ; int 28h interrupt routine.
  67.  
  68. Oldint28 DD    0
  69.  
  70. int28    PROC    FAR
  71.  
  72.     sti            ; interrupts back on
  73.     dec    cs:Fuse1    ; decrement the fuse
  74.     jnz    notyet
  75.     dec    cs:Fuse2    ; secondary fuse
  76.     jnz    notyet
  77.  
  78.     push    ax        ; save regs
  79.     push    bx
  80.     push    cx
  81.     push    dx
  82.     push    bp
  83.     push    si
  84.     push    di
  85.     push    ds
  86.     push    es
  87.  
  88.     mov    ax,cs        ; set ds and es
  89.     mov    ds,ax
  90.     mov    es,ax
  91.  
  92. ; Demand a cookie and wait for the response.
  93.  
  94.     call    getcookie
  95.  
  96. ; Got it.
  97.  
  98.     mov    ax,OFFSET Yum    ; say yum
  99.     mov    Messptr,ax
  100.     mov    ax,Yumlen    ; number of bytes in Yum
  101.     mov    Messcnt,ax
  102.     call    play
  103.  
  104.     mov    Fuse2,fuselen    ; reset fuse
  105.  
  106.     pop    es        ; restore regs and continue
  107.     pop    ds
  108.     pop    di
  109.     pop    si
  110.     pop    bp
  111.     pop    dx
  112.     pop    cx
  113.     pop    bx
  114.     pop    ax
  115. notyet:
  116.     cli            ; interrupts off
  117.     jmp    cs:Oldint28    ; continue along interrupt chain
  118.  
  119. int28    ENDP
  120.  
  121. ; Get a cookie from the user.
  122.  
  123. getcookie PROC    NEAR
  124.  
  125.     mov    ax,OFFSET Giveme ; ask for a cookie
  126.     mov    Messptr,ax
  127.     mov    ax,Givemelen    ; number of bytes in Giveme
  128.     mov    Messcnt,ax
  129.     call    play
  130.  
  131.     mov    di,OFFSET Buf    ; point to buffer
  132.     mov    si,99        ; 99 chars and room for a nul at the end
  133.  
  134. ; Read characters into a buffer up to a CR.
  135.  
  136. getc:
  137.     xor    ax,ax
  138.     int    16h
  139.     cmp    al,13        ; test for CR
  140.     je    gotit
  141.     dec    si        ; buffer full?
  142.     jz    gotit
  143.     cmp    al,65        ; test for uppercase
  144.     jl    lowerc
  145.     cmp    al,90
  146.     jg    lowerc
  147.     add    al,32        ; convert to lowercase
  148. lowerc:
  149.     mov    BYTE PTR [di],al ; store in buffer
  150.     inc    di
  151.     jmp    SHORT getc    ; back for more
  152. gotit:
  153.     mov    BYTE PTR [di],0 ; nul terminate
  154.  
  155. ; See if he typed "cookie".
  156.  
  157.     mov    ax,OFFSET Cookie
  158.     push    ax
  159.     mov    ax,OFFSET Buf
  160.     push    ax
  161.     call    strcmp
  162.     pop    cx
  163.     pop    cx
  164.     or    ax,ax
  165.     jne    getcookie    ; nope, start again
  166.     ret
  167.  
  168. getcookie ENDP
  169.  
  170. Buf    LABEL    BYTE
  171.     DB    100 DUP (?)
  172.  
  173. Cookie    LABEL    BYTE
  174.     DB    "cookie", 0
  175.  
  176. strcmp    PROC    NEAR
  177.  
  178.     push    bp        ; get frame
  179.     mov    bp,sp
  180.  
  181.     cld
  182.     mov    di,[bp+6]    ; get str2
  183.     mov    si,di        ; copy
  184.     xor    al,al
  185.     xor    cx,cx
  186.     not    cx
  187.     repnz    scasb        ; find its length
  188.     not    cx
  189.  
  190.     mov    di,si        ; get str2
  191.     mov    si,[bp+4]    ; get str1
  192.     repz    cmpsb        ; compare strings
  193.     mov    al,[si-1]    ; compare last byte
  194.     sub    al,[di-1]
  195.     cbw
  196.     pop    bp        ; restore regs and return
  197.     ret
  198.  
  199. strcmp    ENDP
  200.  
  201. ; Keyboard interrupt routine.
  202.  
  203. Oldkbint DD    0
  204.  
  205. kbint    PROC    FAR
  206.  
  207.     push    ax        ; save reg
  208.  
  209.     in    al,60h        ; get char from keyboard - ignore it
  210.     in    al,61h        ; clear keyboard
  211.     mov    ah,al
  212.     or    al,80h
  213.     out    61h,al
  214.     mov    al,ah
  215.     out    61h,al
  216.     mov    al,20h        ; issue EOI
  217.     out    20h,al
  218.  
  219.     pop    ax        ; return
  220.     iret
  221.  
  222. kbint    ENDP
  223.  
  224. play    PROC    NEAR
  225.  
  226. ; Substitute local keyboard interrupt routine.
  227.  
  228.     push    es
  229.     mov    ax,3509h
  230.     int    21h
  231.     mov    WORD PTR Oldkbint,bx
  232.     mov    WORD PTR Oldkbint+2,es
  233.  
  234.     mov    dx,OFFSET kbint
  235.     mov    ax,2509h
  236.     int    21h
  237.  
  238. ; Get vector of current timer interrupt.
  239.  
  240.     mov    ax,3508h
  241.     int    21h
  242.     mov    WORD PTR Oldtmrint,bx
  243.     mov    WORD PTR Oldtmrint+2,es
  244.  
  245. ; Mask timer interrupt.
  246.  
  247.     in    al,21h
  248.     or    al,01h
  249.     out    21h,al
  250.  
  251. ; Plug in the local timer interrupt routine.
  252.  
  253.     mov    dx,OFFSET playtimerint
  254.     mov    ax,2508h
  255.     int    21h
  256.  
  257. ; Rev up timer.
  258.  
  259.     mov    al,tcmode
  260.     out    tcadrc,al
  261.     mov    ax,countr
  262.     out    tcadrd,al
  263.     mov    al,ah
  264.     out    tcadrd,al
  265.  
  266. ; Get pointer to message.
  267.  
  268.     mov    bx,Messptr
  269.     mov    si,Messcnt
  270.  
  271. ; Initialize registers.
  272.  
  273.     mov    bp,0        ; done flag
  274.     mov    ch,[bx]     ; get first byte
  275.     mov    ah,0        ; init count
  276.     in    al,ppiadr    ; get normal ppi state
  277.     and    al,0FDh     ; zero speaker bit
  278.     mov    dl,al        ; save for later
  279.  
  280. ; Unmask timer interrupt.
  281.  
  282.     in    al,21h
  283.     and    al,0FEh
  284.     out    21h,al
  285.     sti
  286.  
  287. ; Test for done.
  288.  
  289. ptfd:    or    bp,bp
  290.     jge    ptfd        ; bp negative means done
  291.  
  292. ; Mask timer interrupt.
  293.  
  294.     cli
  295.     in    al,21h
  296.     or    al,01h
  297.     out    21h,al
  298.     sti
  299.  
  300. ; Fix timer.
  301.  
  302.     mov    al,tcmode
  303.     out    tcadrc,al
  304.     mov    al,0
  305.     out    tcadrd,al
  306.     out    tcadrd,al
  307.  
  308. ; Restore original timer interrupt vector.
  309.  
  310.     push    ds
  311.     lds    dx,cs:Oldtmrint
  312.     mov    ax,2508h
  313.     int    21h
  314.     pop    ds
  315.  
  316. ; Unmask timer interrupt.
  317.  
  318.     in    al,21h
  319.     and    al,0FEh
  320.     out    21h,al
  321.  
  322. ; Restore keyboard interrupt vector.
  323.  
  324.     push    ds
  325.     lds    dx,cs:Oldkbint
  326.     mov    ax,2509h
  327.     int    21h
  328.     pop    ds
  329.  
  330. ; Figure out how long the system 18.2 Hz timer has been off.
  331.  
  332.     mov    ax,countr
  333.     shl    ax,1
  334.     shl    ax,1
  335.     shl    ax,1
  336.     mov    cx,Messcnt
  337.     mul    cx
  338.  
  339. ; Adjust the bios time of day to catch up.
  340.  
  341.     mov    ax,40h
  342.     mov    es,ax
  343.     mov    bx,6Ch
  344.     cli
  345.     add    es:[bx],dx
  346.     adc    WORD PTR es:[bx+2],0
  347.     cmp    WORD PTR es:[bx+2],18h
  348.     jb    biosfixed
  349.     ja    wrap
  350.     cmp    WORD PTR es:[bx],0B0h
  351.     jb    biosfixed
  352. wrap:
  353.     sub    WORD PTR es:[bx],0B0h
  354.     sbb    WORD PTR es:[bx+2],18h
  355. biosfixed:
  356.     sti
  357.  
  358. ; Exit.
  359.  
  360.     pop    es
  361.     ret
  362.  
  363. play    ENDP
  364.  
  365. ; Timer interrupt routine.
  366.  
  367. Oldtmrint DD    0
  368.  
  369. playtimerint PROC FAR
  370.  
  371.     or    bp,bp
  372.     jl    ptmrint1
  373.  
  374.     sub    al,al
  375.     rcl    ch,1
  376.     rcl    al,1
  377.     rcl    al,1
  378.     or    al,dl
  379.     out    ppiadr,al
  380.  
  381.     inc    ah
  382.     cmp    ah,8
  383.     jne    ptmrint1
  384.     sub    ah,ah
  385.  
  386.     inc    bx
  387.     mov    ch,[bx]
  388.     dec    si
  389.     or    si,si
  390.     jnz    ptmrint1
  391.     or    bp,8000h    ; done - ensure bp negative
  392.  
  393. ptmrint1:
  394.     mov    al,20h
  395.     out    20h,al
  396.     iret
  397.  
  398. playtimerint ENDP
  399.  
  400. TEXT    ENDS
  401.  
  402. HIGHMEM SEGMENT BYTE
  403. HIGHMEM ENDS
  404.  
  405.     END    start
  406.